package com.example.demo.service;

import com.example.demo.entity.Socket;
import com.example.demo.nios.NonBlockingSocketChannelServer;
import com.example.demo.repository.SocketRepository;
import com.example.demo.req.SocketReq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.SocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.util.*;
import java.util.stream.Collectors;

@Component
@Slf4j
public class SocketServiceImpl implements SocketService {
    @Autowired
    private SocketRepository socketRepository;
    @Override
    public boolean isStartAll(Integer state) {
        List<Socket> sockets = copyIterator(socketRepository.findAll().iterator());
        boolean flag = true; ;
        switch (state){
            case 0:
               flag =  stop(state,sockets);
                break;
            case 1:
              flag  =  isStart(state,sockets);
              break;
        }
        return flag;
    }

    /**
     * 开启服务
     * @param state
     * @param socketReqList
     * @return
     */
    @Override
    public boolean isStart(Integer state, List<Socket> socketReqList) {
        boolean flag  = true;
        //批量修改数据库
        Map<Integer, ServerSocketChannel> serverMap = NonBlockingSocketChannelServer.SERVER_MAP;
        for (Socket socketReq : socketReqList) {
            //启动服务
            Socket socket = socketRepository.findByPort(socketReq.getPort());
            if(socket == null){
                socket = new Socket();
                socket.setIp(socketReq.getIp());
                socket.setPort(socketReq.getPort());
            }
            socket.setState(1);
            try {
            ServerSocketChannel serverSocketChannel = serverMap.get(socketReq.getPort());
            if(serverSocketChannel != null) {
                if(serverSocketChannel.isOpen()){
                  continue;
                }
            }
                NonBlockingSocketChannelServer.AcceptSocketThread server = new NonBlockingSocketChannelServer.AcceptSocketThread();
                server.setIp(socketReq.getIp());
                server.setPort(socketReq.getPort());
                server.start();
                //保存数据库
                //读取
                NonBlockingSocketChannelServer.ReadMsgThread readMsgThread = new NonBlockingSocketChannelServer.ReadMsgThread();
                readMsgThread.start();
                NonBlockingSocketChannelServer.ConsumerMsgThread consumerMsgThread = new NonBlockingSocketChannelServer.ConsumerMsgThread();
                consumerMsgThread.start();
            } catch (Exception e) {
                flag = false;
                e.printStackTrace();
                socket.setState(0);
            }
            finally {
                socketRepository.save(socket);
            }

        }
        return flag;
    }

    /**
     * 关闭服务
     * @param state
     * @param socketReqList
     * @return
     */
    public boolean stop(Integer state, List<Socket> socketReqList) {
        boolean flag  = true;
        //批量修改数据库
        Map<Integer, ServerSocketChannel> serverMap = NonBlockingSocketChannelServer.SERVER_MAP;
        List<Integer> ports = socketReqList.stream().map(item -> {
            return item.getPort();
        }).collect(Collectors.toList());
        List<Socket> sockets = socketRepository.findByPortIn(ports);
        sockets = sockets.stream().map(item -> {
            item.setState(state);
            return item;
        }).collect(Collectors.toList());
        socketRepository.saveAll(sockets);
        for (Socket socket : sockets) {
            ServerSocketChannel serverSocketChannel = serverMap.get(socket.getPort());
            try {
                if(serverSocketChannel!=null) {
                    serverSocketChannel.close();
                    serverMap.remove(serverSocketChannel);
                }
            } catch (IOException e) {
                flag = false;
                e.printStackTrace();
            }
        }
        return flag;
    }

    @Override
    public List<Socket> state(List<Socket> socketReqs) {
        List<Integer> posts  = socketReqs.stream().map(item->{return item.getPort();}).collect(Collectors.toList());
        List<Socket> sockets = socketRepository.findByPortIn(posts);
        Map<Integer, ServerSocketChannel> serverMap = NonBlockingSocketChannelServer.SERVER_MAP;
        for (Socket socket : sockets) {
            ServerSocketChannel serverSocketChannel = serverMap.get(socket.getPort());
            if(serverSocketChannel == null || !serverSocketChannel.isOpen()){
                socket.setState(0);
                continue;
            }
            socket.setState(1);
        }
        socketRepository.saveAll(sockets);

        return sockets;
    }

    @Override
    public List<Socket> allState() {
        Iterable<Socket> all = socketRepository.findAll();
        List<Socket> sockets = copyIterator(all.iterator());
        return this.state(sockets);
    }
    public List<Socket> parse(List<SocketReq> socketReqs){
        List<Socket> list = new ArrayList<>();
        for (SocketReq socketReq : socketReqs) {
            Socket socket = new Socket();
            BeanUtils.copyProperties(socketReq,socket);
            list.add(socket);
        }
        return list;
    }
    public <T> List<T> copyIterator(Iterator<T> iter) {
        List<T> copy = new ArrayList<T>();
        while (iter.hasNext())
            copy.add(iter.next());
        return copy;
    }
}
